﻿using System;
using System.Windows;
using Microsoft.Phone.Controls;

namespace NetworkChangeDetector
{
    using System.Collections.ObjectModel;
    using Microsoft.Phone.Net.NetworkInformation;
    using Microsoft.Phone.Tasks;

    public partial class MainPage : PhoneApplicationPage
    {
        // List of all changes detected while the app is running.
        public ObservableCollection<string> Changes { get; set; }

        // List of all currently available network interfaces
        public ObservableCollection<string> NetworkInterfaces { get; set; }

        public bool IsZuneConnected
        {
            get
            {
                foreach (var ni in NetworkInterfaces)
                {
                    if (ni.Contains("Ethernet") && !ni.Contains("Loopback"))
                        return true;
                }
                return false;
            }
        }

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Initialize the NetworkChanges list.
            Changes = new ObservableCollection<string>();

            // Bind the ListBox to the NetworkChanges list
            lbNetworkChanges.DataContext = Changes;

            NetworkInterfaces = new ObservableCollection<string>();
            lbNetworkInterfaces.DataContext = NetworkInterfaces;

            // Subscribe to the NetworkAvailabilityChanged event
            DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);

            UpdateNetworkInterfaces();
            UpdateNetworkStatus();
        }

        // In this callback, we examine the msg that was detected. In this example, we are
        // creating a simple information string and adding that to the event list on the UI.
        // In a real application, this is where you might adjust your communication connection
        // in order to take advantage of a network availability msg.
        private void ChangeDetected(object sender, NetworkNotificationEventArgs e)
        {
            string change = string.Empty;
            switch (e.NotificationType)
            {
                case NetworkNotificationType.InterfaceConnected:
                    change = "Connected to ";
                    break;
                case NetworkNotificationType.InterfaceDisconnected:
                    change = "Disconnected from ";
                    break;
                case NetworkNotificationType.CharacteristicUpdate:
                    change = "Characteristics changed for ";
                    break;
                default:
                    change = "Unknown change with ";
                    break;
            }

            string changeInformation = String.Format(" {0} {1} {2} ({3})",
                        DateTime.Now.ToString(), change, e.NetworkInterface.InterfaceName,
                        e.NetworkInterface.InterfaceType.ToString());

            // We are making UI updates, so make sure these happen on the UI thread.
            Dispatcher.BeginInvoke(() =>
            {
                Changes.Add(changeInformation);
                UpdateNetworkInterfaces();
                UpdateNetworkStatus();
            });
        }

        private void UpdateNetworkInterfaces()
        {
            NetworkInterfaces.Clear();
            NetworkInterfaceList networkInterfaceList = new NetworkInterfaceList();
            foreach (NetworkInterfaceInfo networkInterfaceInfo in networkInterfaceList)
            {
                //NetworkInterfaces.Add(networkInterfaceInfo.InterfaceName);
                string intf = String.Format(" {0}({1})",
                        networkInterfaceInfo.InterfaceName,
                        networkInterfaceInfo.InterfaceType.ToString());
                NetworkInterfaces.Add(intf);
            }
        }

        private void UpdateNetworkStatus()
        {
            tbIsCellularDataEnabled.Text = (DeviceNetworkInformation.IsCellularDataEnabled) ? "Yes" : "No";
            //tbIsNetworkAvailable.Text = (DeviceNetworkInformation.IsNetworkAvailable) ? "Yes" : "No";
            tbIsNetworkAvailable.Text = NetworkInterface.GetIsNetworkAvailable() ? "Yes" : "No";
            tbIsWiFiEnabled.Text = (DeviceNetworkInformation.IsWiFiEnabled) ? "Yes" : "No";
            tbIsZuneConnected.Text = IsZuneConnected ? "Yes" : "No";
            tbCurrentNetworkType.Text = NetworkInterface.NetworkInterfaceType.ToString();
        }

        // For testing purposes, we provide a way to msg the network connection
        // settings by launching the ConnectionSettingsTask. However, because we are moving
        // our application to the background and then to the foreground when we navigate back from
        // the ConnectionSettingTask, there is a chance we may not receive all NetworkAvailabilityChanged events.
        // Alternatively, you can test by physically disconnecting a Wi-Fi connection, by connecting and disconnecting
        // your device to your desktop, or by moving out of range of your Wi-Fi network.
        private void btnChangeNetworkSettings_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("This action will launch the ConnectionSettingsTask where you can change the network settings." +
                                " As soon as you have made your changes, use the hardware Back button to get back to this page so that you can observe the NetworkAvailabilityChanged events.");

            //Use the ConnectionSettingsTask to bring up the connection settings
            ConnectionSettingsTask connectionSettings = new ConnectionSettingsTask();

            // We are using the Connection Settings page for AirplaneMode.
            connectionSettings.ConnectionSettingsType = ConnectionSettingsType.AirplaneMode;
            connectionSettings.Show();

            // Note: Once you have changed the settings (switched from On to Off for example)
            // use the hardware Back button on your device to go back to this page and catch
            // the NetworkAvailabilityChanged events.
        }

        private void btnRefreshNetwork_Click(object sender, RoutedEventArgs e)
        {
            UpdateNetworkInterfaces();
            UpdateNetworkStatus();
        }
    }
}